﻿#pragma once
#include<iostream>
#include<numeric>
#include<algorithm>
#include<thread>
#include<vector>
#include<windows.h>
#include<math.h>
#include<conio.h>
using namespace std;
const int amount = 2;
const int Flooramount = 8;//0层代表-1楼
int Floor[Flooramount];
class DestList : vector<int>
{
public:
	int currentposition, currentdirection;
	DestList()
	{

	}
	DestList(int position, int direction);
	template<typename T>
	bool Contains(T x);
	void Add(int i);
	void Remove(int i);
	int next();
};
template<typename T>
bool DestList::Contains(T x)
{
	if (empty())
		return false;
	if (find(begin(), end(), x) != end())
		return true;
	else
		return false;
}
DestList::DestList(int position, int direction)
{
	currentposition = position;
	currentdirection = direction;
}
void DestList::Add(int i)
{
	push_back(i);
}
void DestList::Remove(int i)
{
	vector<int>::iterator itr = begin();
	while (itr != end())
	{
		if (*itr == i)
		{
			itr = erase(itr);
		}
		else
			itr++;//这里迭代器会更新出错
	}
}
int DestList::next()
{
	currentposition += currentdirection;
	if (currentposition < 0 || currentposition > Flooramount)
	{
		currentdirection *= -1;
		currentposition += currentdirection;
	}
	return currentposition;
}
class Elevator
{
public:
	int id;
	Elevator();
	Elevator(int i);
	void Adddestination(int i);
	void arrived();
	int nextpos();
	void run();
private:
	int position, direction, weight, maxweight, speed, maxspeed;
	int destination = -1;
	DestList *destlist;
	
	int relativeState(int dest);
	bool isBestState(int dest);
	bool isdestination(int dest);
};
static Elevator elevator[amount];
void postthread()
{
	while (true)
	{
		elevator[0].run();
		elevator[1].run();
		Sleep(100);
	}
}
thread elevatorthread(postthread);
void elevatorstarter()
{
	for (int i = 0; i < amount; i++)
		elevator[i].id = i;
	/*elevator[0].AddDestination(4);
	elevator[0].AddDestination(1);
	elevator[0].AddDestination(2);
	elevator[0].AddDestination(3);
	elevator[0].AddDestination(4);
	elevator[0].AddDestination(5);
	elevator[0].AddDestination(6);
	elevator[0].AddDestination(7);
	elevator[0].AddDestination(8);*/
	//Elevator.floor[3] = 1;
	/*Elevator.floor[1] = 1;
	Elevator.floor[2] = 1;
	Elevator.floor[3] = 1;
	Elevator.floor[4] = 1;
	Elevator.floor[5] = 1;
	Elevator.floor[6] = 1;
	Elevator.floor[7] = -1;*/
	Floor[6] = -1;
	elevatorthread.join();
}
Elevator::Elevator()
{
	int temp = -1;
	cout << "请输入电梯的位置：";
	while (temp < 0 || temp > Flooramount)
		temp = _getch() - '0';
	position = temp;
	direction = 0;
	destlist = new DestList(position, direction);
	cout << position << "\n";
}

inline Elevator::Elevator(int i)
{
	int temp = -1;
	id = i;
	cout << "请输入电梯" << i << "的位置：";
	while (temp < 0 || temp > Flooramount)
		temp = _getch() - '0';
	position = temp;
	direction = 0;
	destlist = new DestList(position, direction);
	cout << position << "\n";
}

inline void Elevator::Adddestination(int i)
{
	if (!destlist->Contains(i) && i >= 0 && i <= Flooramount)
		destlist->Add(i);
}

inline void Elevator::arrived()
{
	if (destlist->Contains(position) || Floor[position] == direction)
	{
		if (destlist->Contains(position))
			destlist->Remove(position);
		if (Floor[position] == direction)
			Floor[position] = 0;
		cout << "电梯" << id << "已到达：" << position << endl;
	}
}

inline int Elevator::nextpos()
{
	if (direction == 0)
	{
		int distance = Flooramount, nearest = 0;
		for (int i = 0; i< Flooramount; i++)
		{
			if ((Floor[i] != 0 || destlist->Contains(i)) && abs(i - position) < distance)
				nearest = i;
		}
		if (nearest <= position)
			direction = -1;
		else
			direction = 1;
	}
	destlist->currentposition = position;
	destlist->currentdirection = direction;
	if (Floor[position] == direction || destlist->Contains(position))
		return position;
	for (int i = 0; i<2 * (Flooramount + 1); i++)
	{
		if (position == 0)
			direction = 1;
		else if (position == Flooramount)
			direction = -1;
		int currentposition = destlist->next();
		if (Floor[currentposition] == destlist->currentdirection && isdestination(currentposition))
		{
			return currentposition;
		}
		if (destlist->Contains(currentposition))
			return currentposition;
	}
	return -1;
}

inline void Elevator::run()
{
	destination = nextpos();
	if (destination == position)
		destination = -1;
	if (destination == -1)
	{
		arrived();
		return;
	}
	else if (destination > position)
	{
		direction = 1;
		position += 1;
	}
	else
	{
		direction = -1;
		position -= 1;
	}
	if (position == 0)
		direction = 1;
	else if (position == Flooramount)
		direction = -1;
	cout << "电梯" << id << "到达：" << position << "，当前目的地：" << destination << "，方向为" << direction << endl;

}

inline int Elevator::relativeState(int dest)
{
	if (Floor[dest] == direction)
	{
		if (direction * (dest - position) > 0)
			return 0;
		else
			return 2;
	}
	else
		return 1;
}

inline bool Elevator::isBestState(int dest)
{
	int state = relativeState(dest);
	for (int i = 0; i < amount; i++)
	{
		if (relativeState(dest)<state)
			return false;
	}
	return true;
}

inline bool Elevator::isdestination(int dest)
{
	int distance = abs(position - dest);
	for (int i = 0; i<amount; i++)
	{
		if (elevator[i].destination == -1 && abs(elevator[i].position - dest) < distance)
		{
			return false;
		}//
		if (elevator[i].destination == dest)
		{//
			if (abs(dest - position) > abs(dest - elevator[i].position))
				return false;//
			else if (relativeState(dest)<elevator[i].relativeState(dest))
				return true;
		}
	}
	return true;
}
void main()
{
	elevatorstarter();
}